import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;


public class Functions {
	public static List<String> find(DFA regex, String sourceFilename) {
		Scanner input = readFile(sourceFilename);
		List<String> matches = new LinkedList<String>();
		for (Token result: regex.tokenize(input)) {
			matches.add(0, result.getString());
		}
		return matches;
	}
	public static void replace(DFA regex, String replacement, String sourceFilename, String destinationFilename) {
		if (sourceFilename.equals(destinationFilename)) {
			throw new IllegalArgumentException("Source filename can't be the same as the target filename.");
		}
		Scanner input = readFile(sourceFilename);
		PrintStream out = writeFile(destinationFilename);
		List<Result> results = regex.tokenize(input);
		input.close();
		Scanner secondPass = readFile(sourceFilename);
		for (Result result: results) {
			String sourceLine = secondPass.nextLine();
			out.print(sourceLine.substring(0, result.start) + replacement + sourceLine.substring(result.stop));
		}
		secondPass.close();
		out.close();
	}
	
	public static void recursivereplace(DFA regex, String replacement, String sourceFilename, String destinationFilename) {
		if (sourceFilename.equals(destinationFilename)) {
			throw new IllegalArgumentException("Source filename can't be the same as the target filename.");
		}
		
		boolean isCyclical = false;
		while (!isCyclical) {
			Scanner input = readFile(sourceFilename);
			PrintStream out = writeFile(destinationFilename);
			List<Result> results = regex.tokenize(input);
			input.close();
			Scanner secondPass = readFile(sourceFilename);
			for (Result result: results) {
				String sourceLine = secondPass.nextLine();
				String newLine = sourceLine.substring(0, result.start) + replacement + sourceLine.substring(result.stop);
				out.print(newLine);
				if (!sourceLine.equals(newLine)) {
					isCyclical = false;
				}
			}
			secondPass.close();
			out.close();
		}
	}
	
	public static String[] union(String[] A, String[] B) {
		List<String> out = new ArrayList<String>();
		List<String> bList = Arrays.asList(B);
		for (String a: A) {
			out.add(a);
		}
		out.addAll(bList);
		return (String[]) out.toArray();
	}
	
	public static String[] diff(String[] A, String[] B) {
		List<String> out = new ArrayList<String>();
		List<String> bList = Arrays.asList(B);
		for (String str: A) {
			out.add(str);
		}
		out.removeAll(bList);
		return (String[]) out.toArray();
	}
	public static String[] inters(String[] A, String[] B) {
		List<String> out = new ArrayList<String>();
		List<String> bList = Arrays.asList(B);
		for (String str: A) {
			if (bList.contains(str)) {
				out.add(str);
			}
		}
		return (String[]) out.toArray();
	}
	
	public static String maxfreqstring(String[] A) {
		Map<String, Integer> counts = new HashMap<String, Integer>();
		int highestCount = -1;
		String mostCommon = "";
		for (String str: A) {
			if (counts.containsKey(str)) {
				counts.put(str, counts.get(str) + 1);
			}
			else {
				counts.put(str, 1);
			}
		}
		for (String word: A) {
			if (counts.get(word) > highestCount) {
				mostCommon = word;
				highestCount = counts.get(word);
			}
		}
		return mostCommon;
	}

	
	public static Scanner readFile(String filename) {
		Scanner results= null;
		File inputFile= new File("./" + filename);
		try {
			results = new Scanner(new BufferedReader(new FileReader(inputFile)));
		} catch (FileNotFoundException error) {
			// TODO Auto-generated catch block
			error.printStackTrace();
		}
		return results;
	}
	private static PrintStream writeFile(String filename) {
		File outputFile = new File("./" + filename);
		PrintStream output = null;
		try {
			boolean alreadyCreated = !outputFile.createNewFile();
			if (alreadyCreated) {
				outputFile.delete();
				outputFile.createNewFile();
			}
		} catch (IOException error1) {
			// TODO Auto-generated catch block
			error1.printStackTrace();
		}
		try {
			output = new PrintStream(new FileOutputStream(outputFile));
		} catch (FileNotFoundException error) {
			// TODO Auto-generated catch block
			error.printStackTrace();
		}
		return output;
	}
}
